///*
// * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
// * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
// *
// *
// *
// *
// *
// *
// *
// *
// *
// *
// *
// *
// *
// *
// *
// *
// *
// *
// *
// *
// */
//package com.sun.java.swing.plaf.gtk;
//
//import sun.awt.UNIXToolkit;
//
//import javax.swing.plaf.synth.*;
//import java.awt.*;
//import javax.swing.*;
//import javax.swing.border.*;
//import javax.swing.plaf.*;
//import com.sun.java.swing.plaf.gtk.GTKConstants.ArrowType;
//import com.sun.java.swing.plaf.gtk.GTKConstants.ExpanderStyle;
//import com.sun.java.swing.plaf.gtk.GTKConstants.Orientation;
//import com.sun.java.swing.plaf.gtk.GTKConstants.PositionType;
//import com.sun.java.swing.plaf.gtk.GTKConstants.ShadowType;
//import java.lang.reflect.InvocationTargetException;
//import java.lang.reflect.Method;
//
///**
// * @author Joshua Outwater
// * @author Scott Violet
// */
//// Need to support:
//// default_outside_border: Insets when default.
//// interior_focus: Indicates if focus should appear inside border, or
////                       outside border.
//// focus-line-width: Integer giving size of focus border
//// focus-padding: Integer giving padding between border and focus
////        indicator.
//// focus-line-pattern:
////
//class GTKPainter extends SynthPainter {
//    private static final PositionType[] POSITIONS = {
//        PositionType.BOTTOM, PositionType.RIGHT,
//        PositionType.TOP, PositionType.LEFT
//    };
//
//    private static final ShadowType SHADOWS[] = {
//        ShadowType.NONE, ShadowType.IN, ShadowType.OUT,
//        ShadowType.ETCHED_IN, ShadowType.OUT
//    };
//
//    private final static GTKEngine ENGINE = GTKEngine.INSTANCE;
//    final static GTKPainter INSTANCE = new GTKPainter();
//
//    private GTKPainter() {
//    }
//
//    private String getName(SynthContext context) {
//        return (context.getRegion().isSubregion()) ? null :
//               context.getComponent().getName();
//    }
//
//    public void paintCheckBoxBackground(SynthContext context,
//            Graphics g, int x, int y, int w, int h) {
//        paintRadioButtonBackground(context, g, x, y, w, h);
//    }
//
//    public void paintCheckBoxMenuItemBackground(SynthContext context,
//            Graphics g, int x, int y, int w, int h) {
//        paintRadioButtonMenuItemBackground(context, g, x, y, w, h);
//    }
//
//    // FORMATTED_TEXT_FIELD
//    public void paintFormattedTextFieldBackground(SynthContext context,
//                                          Graphics g, int x, int y,
//                                          int w, int h) {
//        paintTextBackground(context, g, x, y, w, h);
//    }
//
//    //
//    // TOOL_BAR_DRAG_WINDOW
//    //
//    public void paintToolBarDragWindowBackground(SynthContext context,
//                                     Graphics g, int x, int y,
//                                     int w, int h) {
//        paintToolBarBackground(context, g, x, y, w, h);
//    }
//
//
//    //
//    // TOOL_BAR
//    //
//    public void paintToolBarBackground(SynthContext context,
//                                     Graphics g, int x, int y,
//                                     int w, int h) {
//        Region id = context.getRegion();
//        int state = context.getComponentState();
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(id, state);
//        int orientation = ((JToolBar)context.getComponent()).getOrientation();
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h, id,
//                                          state, orientation))
//            {
//                ENGINE.startPainting(g, x, y, w, h, id, state, orientation);
//                ENGINE.paintBox(g, context, id, gtkState, ShadowType.OUT,
//                                "handlebox_bin", x, y, w, h);
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    public void paintToolBarContentBackground(SynthContext context,
//                                              Graphics g,
//                                              int x, int y, int w, int h) {
//        Region id = context.getRegion();
//        int orientation = ((JToolBar)context.getComponent()).getOrientation();
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h, id, orientation)) {
//                ENGINE.startPainting(g, x, y, w, h, id, orientation);
//                ENGINE.paintBox(g, context, id, SynthConstants.ENABLED,
//                                ShadowType.OUT, "toolbar", x, y, w, h);
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    //
//    // PASSWORD_FIELD
//    //
//    public void paintPasswordFieldBackground(SynthContext context,
//                                     Graphics g, int x, int y,
//                                     int w, int h) {
//        paintTextBackground(context, g, x, y, w, h);
//    }
//
//    //
//    // TEXT_FIELD
//    //
//    public void paintTextFieldBackground(SynthContext context, Graphics g,
//                                         int x, int y, int w, int h) {
//        if (getName(context) == "Tree.cellEditor") {
//            paintTreeCellEditorBackground(context, g, x, y, w, h);
//        } else {
//            paintTextBackground(context, g, x, y, w, h);
//        }
//    }
//
//    //
//    // RADIO_BUTTON
//    //
//    // NOTE: this is called for JCheckBox too
//    public void paintRadioButtonBackground(SynthContext context,
//                                     Graphics g, int x, int y,
//                                     int w, int h) {
//        Region id = context.getRegion();
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(
//                id, context.getComponentState());
//        if (gtkState == SynthConstants.MOUSE_OVER) {
//            synchronized (UNIXToolkit.GTK_LOCK) {
//                if (! ENGINE.paintCachedImage(g, x, y, w, h, id)) {
//                    ENGINE.startPainting(g, x, y, w, h, id);
//                    ENGINE.paintFlatBox(g, context, id,
//                            SynthConstants.MOUSE_OVER, ShadowType.ETCHED_OUT,
//                            "checkbutton", x, y, w, h, ColorType.BACKGROUND);
//                    ENGINE.finishPainting();
//                }
//            }
//        }
//    }
//
//    //
//    // RADIO_BUTTON_MENU_ITEM
//    //
//    // NOTE: this is called for JCheckBoxMenuItem too
//    public void paintRadioButtonMenuItemBackground(SynthContext context,
//                                     Graphics g, int x, int y,
//                                     int w, int h) {
//        Region id = context.getRegion();
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(
//                id, context.getComponentState());
//        if (gtkState == SynthConstants.MOUSE_OVER) {
//            synchronized (UNIXToolkit.GTK_LOCK) {
//                if (! ENGINE.paintCachedImage(g, x, y, w, h, id)) {
//                    ShadowType shadow = (GTKLookAndFeel.is2_2() ?
//                        ShadowType.NONE : ShadowType.OUT);
//                    ENGINE.startPainting(g, x, y, w, h, id);
//                    ENGINE.paintBox(g, context, id, gtkState,
//                            shadow, "menuitem", x, y, w, h);
//                    ENGINE.finishPainting();
//                }
//            }
//        }
//    }
//
//    //
//    // LABEL
//    //
//    public void paintLabelBackground(SynthContext context,
//                                     Graphics g, int x, int y,
//                                     int w, int h) {
//        String name = getName(context);
//        JComponent c = context.getComponent();
//        Container  container = c.getParent();
//
//        if (name == "TableHeader.renderer" ||
//            name == "GTKFileChooser.directoryListLabel" ||
//            name == "GTKFileChooser.fileListLabel") {
//
//            paintButtonBackgroundImpl(context, g, Region.BUTTON, "button",
//                    x, y, w, h, true, false, false, false);
//        }
//        /*
//         * If the label is a ListCellRenderer and it's in a container
//         * (CellRendererPane) which is in a JComboBox then we paint the label
//         * as a TextField like a gtk_entry for a combobox.
//         */
//        else if (c instanceof ListCellRenderer &&
//                 container != null &&
//                 container.getParent() instanceof JComboBox ) {
//            paintTextBackground(context, g, x, y, w, h);
//        }
//    }
//
//    //
//    // INTERNAL_FRAME
//    //
//    public void paintInternalFrameBorder(SynthContext context,
//                                      Graphics g, int x, int y,
//                                      int w, int h) {
//        Metacity.INSTANCE.paintFrameBorder(context, g, x, y, w, h);
//    }
//
//    //
//    // DESKTOP_PANE
//    //
//    public void paintDesktopPaneBackground(SynthContext context,
//                                           Graphics g, int x, int y,
//                                           int w, int h) {
//        // Does not call into ENGINE for better performance
//        fillArea(context, g, x, y, w, h, ColorType.BACKGROUND);
//    }
//
//    //
//    // DESKTOP_ICON
//    //
//    public void paintDesktopIconBorder(SynthContext context,
//                                           Graphics g, int x, int y,
//                                           int w, int h) {
//        Metacity.INSTANCE.paintFrameBorder(context, g, x, y, w, h);
//    }
//
//    public void paintButtonBackground(SynthContext context, Graphics g,
//                                      int x, int y, int w, int h) {
//        String name = getName(context);
//        if (name != null && name.startsWith("InternalFrameTitlePane.")) {
//            Metacity.INSTANCE.paintButtonBackground(context, g, x, y, w, h);
//
//        } else {
//            AbstractButton button = (AbstractButton)context.getComponent();
//            boolean paintBG = button.isContentAreaFilled() &&
//                              button.isBorderPainted();
//            boolean paintFocus = button.isFocusPainted();
//            boolean defaultCapable = (button instanceof JButton) &&
//                    ((JButton)button).isDefaultCapable();
//            boolean toolButton = (button.getParent() instanceof JToolBar);
//            paintButtonBackgroundImpl(context, g, Region.BUTTON, "button",
//                    x, y, w, h, paintBG, paintFocus, defaultCapable, toolButton);
//        }
//    }
//
//    private void paintButtonBackgroundImpl(SynthContext context, Graphics g,
//            Region id, String detail, int x, int y, int w, int h,
//            boolean paintBackground, boolean paintFocus,
//            boolean defaultCapable, boolean toolButton) {
//        int state = context.getComponentState();
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (ENGINE.paintCachedImage(g, x, y, w, h, id, state, detail,
//                    paintBackground, paintFocus, defaultCapable, toolButton)) {
//                return;
//            }
//            ENGINE.startPainting(g, x, y, w, h, id, state, detail,
//                paintBackground, paintFocus, defaultCapable, toolButton);
//
//            // Paint the default indicator
//            GTKStyle style = (GTKStyle)context.getStyle();
//            if (defaultCapable && !toolButton) {
//                Insets defaultInsets = style.getClassSpecificInsetsValue(
//                        context, "default-border",
//                        GTKStyle.BUTTON_DEFAULT_BORDER_INSETS);
//
//                if (paintBackground && (state & SynthConstants.DEFAULT) != 0) {
//                    ENGINE.paintBox(g, context, id, SynthConstants.ENABLED,
//                            ShadowType.IN, "buttondefault", x, y, w, h);
//                }
//                x += defaultInsets.left;
//                y += defaultInsets.top;
//                w -= (defaultInsets.left + defaultInsets.right);
//                h -= (defaultInsets.top + defaultInsets.bottom);
//            }
//
//            boolean interiorFocus = style.getClassSpecificBoolValue(
//                    context, "interior-focus", true);
//            int focusSize = style.getClassSpecificIntValue(
//                    context, "focus-line-width",1);
//            int focusPad = style.getClassSpecificIntValue(
//                    context, "focus-padding", 1);
//
//            int totalFocusSize = focusSize + focusPad;
//            int xThickness = style.getXThickness();
//            int yThickness = style.getYThickness();
//
//            // Render the box.
//            if (!interiorFocus &&
//                    (state & SynthConstants.FOCUSED) == SynthConstants.FOCUSED) {
//                x += totalFocusSize;
//                y += totalFocusSize;
//                w -= 2 * totalFocusSize;
//                h -= 2 * totalFocusSize;
//            }
//
//            int gtkState = GTKLookAndFeel.synthStateToGTKState(id, state);
//            boolean paintBg;
//            if (toolButton) {
//                // Toolbar buttons should only have their background painted
//                // in the PRESSED, SELECTED, or MOUSE_OVER states.
//                paintBg =
//                    (gtkState != SynthConstants.ENABLED) &&
//                    (gtkState != SynthConstants.DISABLED);
//            } else {
//                // Otherwise, always paint the button's background, unless
//                // the user has overridden it and we're in the ENABLED state.
//                paintBg =
//                    paintBackground ||
//                    (gtkState != SynthConstants.ENABLED);
//            }
//            if (paintBg) {
//                ShadowType shadowType = ShadowType.OUT;
//                if ((state & (SynthConstants.PRESSED |
//                              SynthConstants.SELECTED)) != 0) {
//                    shadowType = ShadowType.IN;
//                }
//                ENGINE.paintBox(g, context, id, gtkState,
//                        shadowType, detail, x, y, w, h);
//            }
//
//            // focus
//            if (paintFocus && (state & SynthConstants.FOCUSED) != 0) {
//                if (interiorFocus) {
//                    x += xThickness + focusPad;
//                    y += yThickness + focusPad;
//                    w -= 2 * (xThickness + focusPad);
//                    h -= 2 * (yThickness + focusPad);
//                } else {
//                    x -= totalFocusSize;
//                    y -= totalFocusSize;
//                    w += 2 * totalFocusSize;
//                    h += 2 * totalFocusSize;
//                }
//                ENGINE.paintFocus(g, context, id, gtkState, detail, x, y, w, h);
//            }
//            ENGINE.finishPainting();
//        }
//    }
//
//    //
//    // ARROW_BUTTON
//    //
//    public void paintArrowButtonForeground(SynthContext context, Graphics g,
//                                           int x, int y, int w, int h,
//                                           int direction) {
//        Region id = context.getRegion();
//        Component c = context.getComponent();
//        String name = c.getName();
//
//        ArrowType arrowType = null;
//        switch (direction) {
//            case SwingConstants.NORTH:
//                arrowType = ArrowType.UP; break;
//            case SwingConstants.SOUTH:
//                arrowType = ArrowType.DOWN; break;
//            case SwingConstants.EAST:
//                arrowType = ArrowType.RIGHT; break;
//            case SwingConstants.WEST:
//                arrowType = ArrowType.LEFT; break;
//        }
//
//        String detail = "arrow";
//        if ((name == "ScrollBar.button") || (name == "TabbedPane.button")) {
//            if (arrowType == ArrowType.UP || arrowType == ArrowType.DOWN) {
//                detail = "vscrollbar";
//            } else {
//                detail = "hscrollbar";
//            }
//        } else if (name == "Spinner.nextButton" ||
//                   name == "Spinner.previousButton") {
//            detail = "spinbutton";
//        } else if (name != "ComboBox.arrowButton") {
//            assert false : "unexpected name: " + name;
//        }
//
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(
//                id, context.getComponentState());
//        ShadowType shadowType = (gtkState == SynthConstants.PRESSED ?
//            ShadowType.IN : ShadowType.OUT);
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (ENGINE.paintCachedImage(g, x, y, w, h,
//                    gtkState, name, direction)) {
//                return;
//            }
//            ENGINE.startPainting(g, x, y, w, h, gtkState, name, direction);
//            ENGINE.paintArrow(g, context, id, gtkState,
//                    shadowType, arrowType, detail, x, y, w, h);
//            ENGINE.finishPainting();
//        }
//    }
//
//    public void paintArrowButtonBackground(SynthContext context,
//            Graphics g, int x, int y, int w, int h) {
//        Region id = context.getRegion();
//        AbstractButton button = (AbstractButton)context.getComponent();
//
//        String name = button.getName();
//        String detail = "button";
//        int direction = SwingConstants.CENTER;
//        if ((name == "ScrollBar.button") || (name == "TabbedPane.button")) {
//            Integer prop = (Integer)
//                button.getClientProperty("__arrow_direction__");
//            direction = (prop != null) ?
//                prop.intValue() : SwingConstants.WEST;
//            switch (direction) {
//            default:
//            case SwingConstants.EAST:
//            case SwingConstants.WEST:
//                detail = "hscrollbar";
//                break;
//            case SwingConstants.NORTH:
//            case SwingConstants.SOUTH:
//                detail = "vscrollbar";
//                break;
//            }
//        } else if (name == "Spinner.previousButton") {
//            detail = "spinbutton_down";
//        } else if (name == "Spinner.nextButton") {
//            detail = "spinbutton_up";
//        } else if (name != "ComboBox.arrowButton") {
//            assert false : "unexpected name: " + name;
//        }
//
//        int state = context.getComponentState();
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (ENGINE.paintCachedImage(g, x, y, w, h, id,
//                                        state, detail, direction))
//            {
//                return;
//            }
//            ENGINE.startPainting(g, x, y, w, h, id,
//                                 state, detail, direction);
//
//            if (detail.startsWith("spin")) {
//                /*
//                 * The ubuntulooks engine (and presumably others) expect us to
//                 * first draw the full "spinbutton" background, and then draw
//                 * the individual "spinbutton_up/down" buttons on top of that.
//                 * Note that it is the state of the JSpinner (not its arrow
//                 * button) that determines how we draw this background.
//                 */
//                int spinState = button.getParent().isEnabled() ?
//                    SynthConstants.ENABLED : SynthConstants.DISABLED;
//                int mody = (detail == "spinbutton_up") ? y : y-h;
//                int modh = h*2;
//                ENGINE.paintBox(g, context, id, spinState,
//                                ShadowType.IN, "spinbutton",
//                                x, mody, w, modh);
//            }
//
//            int gtkState = GTKLookAndFeel.synthStateToGTKState(id, state);
//            ShadowType shadowType = ShadowType.OUT;
//            if ((gtkState & (SynthConstants.PRESSED |
//                             SynthConstants.SELECTED)) != 0)
//            {
//                shadowType = ShadowType.IN;
//            }
//            ENGINE.paintBox(g, context, id, gtkState,
//                            shadowType, detail,
//                            x, y, w, h);
//
//            ENGINE.finishPainting();
//        }
//    }
//
//
//    //
//    // LIST
//    //
//    public void paintListBackground(SynthContext context, Graphics g,
//                                    int x, int y, int w, int h) {
//        // Does not call into ENGINE for better performance
//        fillArea(context, g, x, y, w, h, GTKColorType.TEXT_BACKGROUND);
//    }
//
//    public void paintMenuBarBackground(SynthContext context, Graphics g,
//                                       int x, int y, int w, int h) {
//        Region id = context.getRegion();
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (ENGINE.paintCachedImage(g, x, y, w, h, id)) {
//                return;
//            }
//            GTKStyle style = (GTKStyle)context.getStyle();
//            int shadow = style.getClassSpecificIntValue(
//                    context, "shadow-type", 2);
//            ShadowType shadowType = SHADOWS[shadow];
//            int gtkState = GTKLookAndFeel.synthStateToGTKState(
//                    id, context.getComponentState());
//            ENGINE.startPainting(g, x, y, w, h, id);
//            ENGINE.paintBox(g, context, id, gtkState,
//                shadowType, "menubar", x, y, w, h);
//            ENGINE.finishPainting();
//        }
//    }
//
//    //
//    // MENU
//    //
//    public void paintMenuBackground(SynthContext context,
//                                     Graphics g,
//                                     int x, int y, int w, int h) {
//        paintMenuItemBackground(context, g, x, y, w, h);
//    }
//
//    // This is called for both MENU and MENU_ITEM
//    public void paintMenuItemBackground(SynthContext context,
//                                     Graphics g,
//                                     int x, int y, int w, int h) {
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(
//                context.getRegion(), context.getComponentState());
//        if (gtkState == SynthConstants.MOUSE_OVER) {
//            Region id = Region.MENU_ITEM;
//            synchronized (UNIXToolkit.GTK_LOCK) {
//                if (! ENGINE.paintCachedImage(g, x, y, w, h, id)) {
//                    ShadowType shadow = (GTKLookAndFeel.is2_2() ?
//                        ShadowType.NONE : ShadowType.OUT);
//                    ENGINE.startPainting(g, x, y, w, h, id);
//                    ENGINE.paintBox(g, context, id, gtkState, shadow,
//                            "menuitem", x, y, w, h);
//                    ENGINE.finishPainting();
//                }
//            }
//        }
//    }
//
//    public void paintPopupMenuBackground(SynthContext context, Graphics g,
//                                        int x, int y, int w, int h) {
//        Region id = context.getRegion();
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(
//                id, context.getComponentState());
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState)) {
//                return;
//            }
//            ENGINE.startPainting(g, x, y, w, h, id, gtkState);
//            ENGINE.paintBox(g, context, id, gtkState,
//                    ShadowType.OUT, "menu", x, y, w, h);
//
//            GTKStyle style = (GTKStyle)context.getStyle();
//            int xThickness = style.getXThickness();
//            int yThickness = style.getYThickness();
//            ENGINE.paintBackground(g, context, id, gtkState,
//                    style.getGTKColor(context, gtkState, GTKColorType.BACKGROUND),
//                    x + xThickness, y + yThickness,
//                    w - xThickness - xThickness, h - yThickness - yThickness);
//            ENGINE.finishPainting();
//        }
//    }
//
//    public void paintProgressBarBackground(SynthContext context,
//                                            Graphics g,
//                                            int x, int y, int w, int h) {
//        Region id = context.getRegion();
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h, id)) {
//                ENGINE.startPainting(g, x, y, w, h, id);
//                ENGINE.paintBox(g, context, id, SynthConstants.ENABLED,
//                        ShadowType.IN, "trough", x, y, w, h);
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    public void paintProgressBarForeground(SynthContext context, Graphics g,
//                                            int x, int y, int w, int h,
//                                            int orientation) {
//        Region id = context.getRegion();
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            // Note that we don't call paintCachedImage() here.  Since the
//            // progress bar foreground is painted differently for each value
//            // it would be wasteful to try to cache an image for each state,
//            // so instead we simply avoid caching in this case.
//            if (w <= 0 || h <= 0) {
//                return;
//            }
//            ENGINE.startPainting(g, x, y, w, h, id, "fg");
//            ENGINE.paintBox(g, context, id, SynthConstants.MOUSE_OVER,
//                            ShadowType.OUT, "bar", x, y, w, h);
//            ENGINE.finishPainting(false); // don't bother caching the image
//        }
//    }
//
//    public void paintViewportBorder(SynthContext context, Graphics g,
//                                           int x, int y, int w, int h) {
//        Region id = context.getRegion();
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h, id)) {
//                ENGINE.startPainting(g, x, y, w, h, id);
//                ENGINE.paintShadow(g, context, id, SynthConstants.ENABLED,
//                        ShadowType.IN, "scrolled_window", x, y, w, h);
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    public void paintSeparatorBackground(SynthContext context,
//                                          Graphics g,
//                                          int x, int y, int w, int h,
//                                         int orientation) {
//        Region id = context.getRegion();
//        int state = context.getComponentState();
//        JComponent c = context.getComponent();
//
//        /*
//         * Note: In theory, the style's x/y thickness values would determine
//         * the width of the separator content.  In practice, however, some
//         * engines will render a line that is wider than the corresponding
//         * thickness value.  For example, ubuntulooks reports x/y thickness
//         * values of 1 for separators, but always renders a 2-pixel wide line.
//         * As a result of all this, we need to be careful not to restrict
//         * the w/h values below too much, so that the full thickness of the
//         * rendered line will be captured by our image caching code.
//         */
//        String detail;
//        if (c instanceof JToolBar.Separator) {
//            /*
//             * GTK renders toolbar separators differently in that an
//             * artificial padding is added to each end of the separator.
//             * The value of 0.2f below is derived from the source code of
//             * gtktoolbar.c in the current version of GTK+ (2.8.20 at the
//             * time of this writing).  Specifically, the relevant values are:
//             *     SPACE_LINE_DIVISION 10.0
//             *     SPACE_LINE_START     2.0
//             *     SPACE_LINE_END       8.0
//             * These are used to determine the distance from the top (or left)
//             * edge of the toolbar to the other edge.  So for example, the
//             * starting/top point of a vertical separator is 2/10 of the
//             * height of a horizontal toolbar away from the top edge, which
//             * is how we arrive at 0.2f below.  Likewise, the ending/bottom
//             * point is 8/10 of the height away from the top edge, or in other
//             * words, it is 2/10 away from the bottom edge, which is again
//             * how we arrive at the 0.2f value below.
//             *
//             * The separator is also centered horizontally or vertically,
//             * depending on its orientation.  This was determined empirically
//             * and by examining the code referenced above.
//             */
//            detail = "toolbar";
//            float pct = 0.2f;
//            JToolBar.Separator sep = (JToolBar.Separator)c;
//            Dimension size = sep.getSeparatorSize();
//            GTKStyle style = (GTKStyle)context.getStyle();
//            if (orientation == JSeparator.HORIZONTAL) {
//                x += (int)(w * pct);
//                w -= (int)(w * pct * 2);
//                y += (size.height - style.getYThickness()) / 2;
//            } else {
//                y += (int)(h * pct);
//                h -= (int)(h * pct * 2);
//                x += (size.width - style.getXThickness()) / 2;
//            }
//        } else {
//            // For regular/menu separators, we simply subtract out the insets.
//            detail = "separator";
//            Insets insets = c.getInsets();
//            x += insets.left;
//            y += insets.top;
//            if (orientation == JSeparator.HORIZONTAL) {
//                w -= (insets.left + insets.right);
//            } else {
//                h -= (insets.top + insets.bottom);
//            }
//        }
//
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h, id,
//                                          state, detail, orientation)) {
//                ENGINE.startPainting(g, x, y, w, h, id,
//                                     state, detail, orientation);
//                if (orientation == JSeparator.HORIZONTAL) {
//                    ENGINE.paintHline(g, context, id, state,
//                                      detail, x, y, w, h);
//                } else {
//                    ENGINE.paintVline(g, context, id, state,
//                                      detail, x, y, w, h);
//                }
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    public void paintSliderTrackBackground(SynthContext context,
//                                       Graphics g,
//                                       int x, int y, int w,int h) {
//        Region id = context.getRegion();
//        int state = context.getComponentState();
//
//        // For focused sliders, we paint focus rect outside the bounds passed.
//        // Need to adjust for that.
//        boolean focused = ((state & SynthConstants.FOCUSED) != 0);
//        int focusSize = 0;
//        if (focused) {
//            GTKStyle style = (GTKStyle)context.getStyle();
//            focusSize = style.getClassSpecificIntValue(
//                                context, "focus-line-width", 1) +
//                        style.getClassSpecificIntValue(
//                                context, "focus-padding", 1);
//            x -= focusSize;
//            y -= focusSize;
//            w += focusSize * 2;
//            h += focusSize * 2;
//        }
//
//        // The ubuntulooks engine paints slider troughs differently depending
//        // on the current slider value and its component orientation.
//        JSlider slider = (JSlider)context.getComponent();
//        double value = slider.getValue();
//        double min = slider.getMinimum();
//        double max = slider.getMaximum();
//        double visible = 20; // not used for sliders; any value will work
//
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            // Note that we don't call paintCachedImage() here.  Since some
//            // engines (e.g. ubuntulooks) paint the slider background
//            // differently for any given slider value, it would be wasteful
//            // to try to cache an image for each state, so instead we simply
//            // avoid caching in this case.
//            if (w <= 0 || h <= 0) {
//                return;
//            }
//            ENGINE.startPainting(g, x, y, w, h, id, state, value);
//            int gtkState = GTKLookAndFeel.synthStateToGTKState(id, state);
//            ENGINE.setRangeValue(context, id, value, min, max, visible);
//            ENGINE.paintBox(g, context, id, gtkState, ShadowType.IN,
//                            "trough", x + focusSize, y + focusSize,
//                            w - 2 * focusSize, h - 2 * focusSize);
//            if (focused) {
//                ENGINE.paintFocus(g, context, id, SynthConstants.ENABLED,
//                                  "trough", x, y, w, h);
//            }
//            ENGINE.finishPainting(false); // don't bother caching the image
//        }
//    }
//
//    public void paintSliderThumbBackground(SynthContext context,
//            Graphics g, int x, int y, int w, int h, int dir) {
//        Region id = context.getRegion();
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(
//                id, context.getComponentState());
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState, dir)) {
//                Orientation orientation = (dir == JSlider.HORIZONTAL ?
//                    Orientation.HORIZONTAL : Orientation.VERTICAL);
//                String detail = (dir == JSlider.HORIZONTAL ?
//                    "hscale" : "vscale");
//                ENGINE.startPainting(g, x, y, w, h, id, gtkState, dir);
//                ENGINE.paintSlider(g, context, id, gtkState,
//                        ShadowType.OUT, detail, x, y, w, h, orientation);
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    //
//    // SPINNER
//    //
//    public void paintSpinnerBackground(SynthContext context,
//                                        Graphics g,
//                                        int x, int y, int w, int h) {
//        // This is handled in paintTextFieldBackground
//    }
//
//    //
//    // SPLIT_PANE_DIVIDER
//    //
//    public void paintSplitPaneDividerBackground(SynthContext context,
//                                       Graphics g,
//                                       int x, int y, int w, int h) {
//        Region id = context.getRegion();
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(
//                id, context.getComponentState());
//        JSplitPane splitPane = (JSplitPane)context.getComponent();
//        Orientation orientation =
//                (splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT ?
//                    Orientation.VERTICAL : Orientation.HORIZONTAL);
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h,
//                    id, gtkState, orientation)) {
//                ENGINE.startPainting(g, x, y, w, h, id, gtkState, orientation);
//                ENGINE.paintHandle(g, context, id, gtkState,
//                        ShadowType.OUT, "paned", x, y, w, h, orientation);
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    public void paintSplitPaneDragDivider(SynthContext context,
//                                       Graphics g,int x, int y, int w, int h,
//                                       int orientation) {
//        paintSplitPaneDividerForeground(context, g, x, y, w, h, orientation);
//    }
//
//    public void paintTabbedPaneContentBackground(SynthContext context,
//                                      Graphics g, int x, int y, int w, int h) {
//        JTabbedPane pane = (JTabbedPane)context.getComponent();
//        int selectedIndex = pane.getSelectedIndex();
//        PositionType placement = GTKLookAndFeel.SwingOrientationConstantToGTK(
//                                                        pane.getTabPlacement());
//
//        int gapStart = 0;
//        int gapSize = 0;
//        if (selectedIndex != -1) {
//            Rectangle tabBounds = pane.getBoundsAt(selectedIndex);
//
//            if (placement == PositionType.TOP ||
//                placement == PositionType.BOTTOM) {
//
//                gapStart = tabBounds.x - x;
//                gapSize = tabBounds.width;
//            }
//            else {
//                gapStart = tabBounds.y - y;
//                gapSize = tabBounds.height;
//            }
//        }
//
//        Region id = context.getRegion();
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(
//                id, context.getComponentState());
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h,
//                    id, gtkState, placement, gapStart, gapSize)) {
//                ENGINE.startPainting(g, x, y, w, h,
//                        id, gtkState, placement, gapStart, gapSize);
//                ENGINE.paintBoxGap(g, context, id, gtkState, ShadowType.OUT,
//                        "notebook", x, y, w, h, placement, gapStart, gapSize);
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    public void paintTabbedPaneTabBackground(SynthContext context,
//                                           Graphics g,
//                                           int x, int y, int w, int h,
//                                           int tabIndex) {
//        Region id = context.getRegion();
//        int state = context.getComponentState();
//        int gtkState = ((state & SynthConstants.SELECTED) != 0 ?
//            SynthConstants.ENABLED : SynthConstants.PRESSED);
//        JTabbedPane pane = (JTabbedPane)context.getComponent();
//        int placement = pane.getTabPlacement();
//
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h,
//                    id, gtkState, placement, tabIndex)) {
//                PositionType side = POSITIONS[placement - 1];
//                ENGINE.startPainting(g, x, y, w, h,
//                        id, gtkState, placement, tabIndex);
//                ENGINE.paintExtension(g, context, id, gtkState,
//                        ShadowType.OUT, "tab", x, y, w, h, side, tabIndex);
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    //
//    // TEXT_PANE
//    //
//    public void paintTextPaneBackground(SynthContext context, Graphics g,
//                                        int x, int y, int w, int h) {
//        paintTextAreaBackground(context, g, x, y, w, h);
//    }
//
//    //
//    // EDITOR_PANE
//    //
//    public void paintEditorPaneBackground(SynthContext context, Graphics g,
//                                          int x, int y, int w, int h) {
//        paintTextAreaBackground(context, g, x, y, w, h);
//    }
//
//    //
//    // TEXT_AREA
//    //
//    public void paintTextAreaBackground(SynthContext context, Graphics g,
//                                        int x, int y, int w, int h) {
//        // Does not call into ENGINE for better performance
//        fillArea(context, g, x, y, w, h, GTKColorType.TEXT_BACKGROUND);
//    }
//
//    //
//    // TEXT_FIELD
//    //
//    // NOTE: Combobox and Label, Password and FormattedTextField calls this
//    // too.
//    private void paintTextBackground(SynthContext context, Graphics g,
//                                     int x, int y, int w, int h) {
//        // Text is odd in that it uses the TEXT_BACKGROUND vs BACKGROUND.
//        JComponent c = context.getComponent();
//        Container container = c.getParent();
//        Container containerParent = null;
//        GTKStyle style = (GTKStyle)context.getStyle();
//        Region id = context.getRegion();
//        int state = context.getComponentState();
//
//        if (c instanceof ListCellRenderer && container != null) {
//            containerParent = container.getParent();
//            if (containerParent instanceof JComboBox
//                    && containerParent.hasFocus()) {
//                state |= SynthConstants.FOCUSED;
//            }
//        }
//
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (ENGINE.paintCachedImage(g, x, y, w, h, id, state)) {
//                return;
//            }
//
//            int gtkState = GTKLookAndFeel.synthStateToGTKState(id, state);
//            int focusSize = 0;
//            boolean interiorFocus = style.getClassSpecificBoolValue(
//                    context, "interior-focus", true);
//
//            focusSize = style.getClassSpecificIntValue(context,
//                    "focus-line-width",1);
//            if (!interiorFocus && (state & SynthConstants.FOCUSED) != 0) {
//                x += focusSize;
//                y += focusSize;
//                w -= 2 * focusSize;
//                h -= 2 * focusSize;
//            }
//
//            int xThickness = style.getXThickness();
//            int yThickness = style.getYThickness();
//
//            ENGINE.startPainting(g, x, y, w, h, id, state);
//            ENGINE.paintShadow(g, context, id, gtkState,
//                               ShadowType.IN, "entry", x, y, w, h);
//            ENGINE.paintFlatBox(g, context, id,
//                                gtkState, ShadowType.NONE, "entry_bg",
//                                x + xThickness,
//                                y + yThickness,
//                                w - (2 * xThickness),
//                                h - (2 * yThickness),
//                                ColorType.TEXT_BACKGROUND);
//
//            if (focusSize > 0 && (state & SynthConstants.FOCUSED) != 0) {
//                if (!interiorFocus) {
//                    x -=  focusSize;
//                    y -=  focusSize;
//                    w +=  2 * focusSize;
//                    h +=  2 * focusSize;
//                } else {
//                    if (containerParent instanceof JComboBox) {
//                        x += (focusSize + 2);
//                        y += (focusSize + 1);
//                        w -= (2 * focusSize + 1);
//                        h -= (2 * focusSize + 2);
//                    } else {
//                        x += focusSize;
//                        y += focusSize;
//                        w -= 2 * focusSize;
//                        h -= 2 * focusSize;
//                    }
//                }
//                ENGINE.paintFocus(g, context, id, gtkState,
//                        "entry", x, y, w, h);
//            }
//            ENGINE.finishPainting();
//        }
//    }
//
//    private void paintTreeCellEditorBackground(SynthContext context, Graphics g,
//                                               int x, int y, int w, int h) {
//        Region id = context.getRegion();
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(
//                id, context.getComponentState());
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState)) {
//                ENGINE.startPainting(g, x, y, w, h, id, gtkState);
//                ENGINE.paintFlatBox(g, context, id, gtkState, ShadowType.NONE,
//                        "entry_bg", x, y, w, h, ColorType.TEXT_BACKGROUND);
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//
//    //
//    // ROOT_PANE
//    //
//    public void paintRootPaneBackground(SynthContext context, Graphics g,
//                                        int x, int y, int w, int h) {
//        // Does not call into ENGINE for better performance
//        fillArea(context, g, x, y, w, h, GTKColorType.BACKGROUND);
//    }
//
//    //
//    // TOGGLE_BUTTON
//    //
//    public void paintToggleButtonBackground(SynthContext context,
//                                            Graphics g,
//                                            int x, int y, int w, int h) {
//        Region id = context.getRegion();
//        JToggleButton toggleButton = (JToggleButton)context.getComponent();
//        boolean paintBG = toggleButton.isContentAreaFilled() &&
//                          toggleButton.isBorderPainted();
//        boolean paintFocus = toggleButton.isFocusPainted();
//        boolean toolButton = (toggleButton.getParent() instanceof JToolBar);
//        paintButtonBackgroundImpl(context, g, id, "button",
//                                  x, y, w, h,
//                                  paintBG, paintFocus, false, toolButton);
//    }
//
//
//    //
//    // SCROLL_BAR
//    //
//    public void paintScrollBarBackground(SynthContext context,
//                                          Graphics g,
//                                          int x, int y, int w,int h) {
//        Region id = context.getRegion();
//        boolean focused =
//                (context.getComponentState() & SynthConstants.FOCUSED) != 0;
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (ENGINE.paintCachedImage(g, x, y, w, h, id, focused)) {
//                return;
//            }
//            ENGINE.startPainting(g, x, y, w, h, id, focused);
//
//            // Note: the scrollbar insets already include the "trough-border",
//            // which is needed to position the scrollbar buttons properly.
//            // But when we render, we need to take the trough border out
//            // of the equation so that we paint the entire area covered by
//            // the trough border and the scrollbar content itself.
//            Insets insets = context.getComponent().getInsets();
//            GTKStyle style = (GTKStyle)context.getStyle();
//            int troughBorder =
//                style.getClassSpecificIntValue(context, "trough-border", 1);
//            insets.left   -= troughBorder;
//            insets.right  -= troughBorder;
//            insets.top    -= troughBorder;
//            insets.bottom -= troughBorder;
//
//            ENGINE.paintBox(g, context, id, SynthConstants.PRESSED,
//                            ShadowType.IN, "trough",
//                            x + insets.left,
//                            y + insets.top,
//                            w - insets.left - insets.right,
//                            h - insets.top - insets.bottom);
//
//            if (focused) {
//                ENGINE.paintFocus(g, context, id,
//                        SynthConstants.ENABLED, "trough", x, y, w, h);
//            }
//            ENGINE.finishPainting();
//        }
//    }
//
//
//    //
//    // SCROLL_BAR_THUMB
//    //
//    public void paintScrollBarThumbBackground(SynthContext context,
//            Graphics g, int x, int y, int w, int h, int dir) {
//        Region id = context.getRegion();
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(
//                id, context.getComponentState());
//
//        // The clearlooks engine paints scrollbar thumbs differently
//        // depending on the current scroll value (specifically, it will avoid
//        // rendering a certain line when the thumb is at the starting or
//        // ending position).  Therefore, we normalize the current value to
//        // the range [0,100] here and then pass it down to setRangeValue()
//        // so that the native widget is configured appropriately.  Note that
//        // there are really only four values that matter (min, middle, max,
//        // or fill) so we restrict to one of those four values to avoid
//        // blowing out the image cache.
//        JScrollBar sb = (JScrollBar)context.getComponent();
//        boolean rtl =
//            sb.getOrientation() == JScrollBar.HORIZONTAL &&
//            !sb.getComponentOrientation().isLeftToRight();
//        double min = 0;
//        double max = 100;
//        double visible = 20;
//        double value;
//        if (sb.getMaximum() - sb.getMinimum() == sb.getVisibleAmount()) {
//            // In this case, the thumb fills the entire track, so it is
//            // touching both ends at the same time
//            value = 0;
//            visible = 100;
//        } else if (sb.getValue() == sb.getMinimum()) {
//            // At minimum
//            value = rtl ? 100 : 0;
//        } else if (sb.getValue() >= sb.getMaximum() - sb.getVisibleAmount()) {
//            // At maximum
//            value = rtl ? 0 : 100;
//        } else {
//            // Somewhere in between
//            value = 50;
//        }
//
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState,
//                                          dir, value, visible, rtl))
//            {
//                ENGINE.startPainting(g, x, y, w, h, id, gtkState,
//                                     dir, value, visible, rtl);
//                Orientation orientation = (dir == JScrollBar.HORIZONTAL ?
//                    Orientation.HORIZONTAL : Orientation.VERTICAL);
//                ENGINE.setRangeValue(context, id, value, min, max, visible);
//                ENGINE.paintSlider(g, context, id, gtkState,
//                        ShadowType.OUT, "slider", x, y, w, h, orientation);
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    //
//    // TOOL_TIP
//    //
//    public void paintToolTipBackground(SynthContext context, Graphics g,
//                                        int x, int y, int w,int h) {
//        Region id = context.getRegion();
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h, id)) {
//                ENGINE.startPainting(g, x, y, w, h, id);
//                ENGINE.paintFlatBox(g, context, id, SynthConstants.ENABLED,
//                        ShadowType.OUT, "tooltip", x, y, w, h,
//                        ColorType.BACKGROUND);
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//
//    //
//    // TREE_CELL
//    //
//    public void paintTreeCellBackground(SynthContext context, Graphics g,
//                                        int x, int y, int w, int h) {
//        Region id = context.getRegion();
//        int state = context.getComponentState();
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(id, state);
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h, id, state)) {
//                ENGINE.startPainting(g, x, y, w, h, id, state);
//                // the string arg should alternate based on row being painted,
//                // but we currently don't pass that in.
//                ENGINE.paintFlatBox(g, context, id, gtkState, ShadowType.NONE,
//                        "cell_odd", x, y, w, h, ColorType.TEXT_BACKGROUND);
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    public void paintTreeCellFocus(SynthContext context, Graphics g,
//                                    int x, int y, int w, int h) {
//        Region id = Region.TREE_CELL;
//        int state = context.getComponentState();
//        paintFocus(context, g, id, state, "treeview", x, y, w, h);
//    }
//
//
//    //
//    // TREE
//    //
//    public void paintTreeBackground(SynthContext context, Graphics g,
//                                    int x, int y, int w, int h) {
//        // As far as I can tell, these don't call into the ENGINE.
//        fillArea(context, g, x, y, w, h, GTKColorType.TEXT_BACKGROUND);
//    }
//
//
//    //
//    // VIEWPORT
//    //
//    public void paintViewportBackground(SynthContext context, Graphics g,
//                                        int x, int y, int w, int h) {
//        // As far as I can tell, these don't call into the ENGINE.
//        // Also note that you don't want this to call into the ENGINE
//        // as if it where to paint a background JViewport wouldn't scroll
//        // correctly.
//        fillArea(context, g, x, y, w, h, GTKColorType.TEXT_BACKGROUND);
//    }
//
//    void paintFocus(SynthContext context, Graphics g, Region id,
//            int state, String detail, int x, int y, int w, int h) {
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(id, state);
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState, "focus")) {
//                ENGINE.startPainting(g, x, y, w, h, id, gtkState, "focus");
//                ENGINE.paintFocus(g, context, id, gtkState, detail, x, y, w, h);
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    void paintMetacityElement(SynthContext context, Graphics g,
//            int gtkState, String detail, int x, int y, int w, int h,
//            ShadowType shadow, ArrowType direction) {
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(
//                    g, x, y, w, h, gtkState, detail, shadow, direction)) {
//                ENGINE.startPainting(
//                        g, x, y, w, h, gtkState, detail, shadow, direction);
//                if (detail == "metacity-arrow") {
//                    ENGINE.paintArrow(g, context, Region.INTERNAL_FRAME_TITLE_PANE,
//                            gtkState, shadow, direction, "", x, y, w, h);
//
//                } else if (detail == "metacity-box") {
//                    ENGINE.paintBox(g, context, Region.INTERNAL_FRAME_TITLE_PANE,
//                            gtkState, shadow, "", x, y, w, h);
//
//                } else if (detail == "metacity-vline") {
//                    ENGINE.paintVline(g, context, Region.INTERNAL_FRAME_TITLE_PANE,
//                            gtkState, "", x, y, w, h);
//                }
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    void paintIcon(SynthContext context, Graphics g,
//            Method paintMethod, int x, int y, int w, int h) {
//        int state = context.getComponentState();
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g, x, y, w, h, state, paintMethod)) {
//                ENGINE.startPainting(g, x, y, w, h, state, paintMethod);
//                try {
//                    paintMethod.invoke(this, context, g, state, x, y, w, h);
//                } catch (IllegalAccessException iae) {
//                    assert false;
//                } catch (InvocationTargetException ite) {
//                    assert false;
//                }
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    void paintIcon(SynthContext context, Graphics g,
//            Method paintMethod, int x, int y, int w, int h, Object direction) {
//        int state = context.getComponentState();
//        synchronized (UNIXToolkit.GTK_LOCK) {
//            if (! ENGINE.paintCachedImage(g,
//                    x, y, w, h, state, paintMethod, direction)) {
//                ENGINE.startPainting(g,
//                        x, y, w, h, state, paintMethod, direction);
//                try {
//                    paintMethod.invoke(this, context,
//                            g, state, x, y, w, h, direction);
//                } catch (IllegalAccessException iae) {
//                    assert false;
//                } catch (InvocationTargetException ite) {
//                    assert false;
//                }
//                ENGINE.finishPainting();
//            }
//        }
//    }
//
//    // All icon painting methods are called from under GTK_LOCK
//
//    public void paintTreeExpandedIcon(SynthContext context,
//            Graphics g, int state, int x, int y, int w, int h) {
//        ENGINE.paintExpander(g, context, Region.TREE,
//                GTKLookAndFeel.synthStateToGTKState(context.getRegion(), state),
//                ExpanderStyle.EXPANDED, "treeview", x, y, w, h);
//    }
//
//    public void paintTreeCollapsedIcon(SynthContext context,
//            Graphics g, int state, int x, int y, int w, int h) {
//        ENGINE.paintExpander(g, context, Region.TREE,
//                GTKLookAndFeel.synthStateToGTKState(context.getRegion(), state),
//                ExpanderStyle.COLLAPSED, "treeview", x, y, w, h);
//    }
//
//    public void paintCheckBoxIcon(SynthContext context,
//            Graphics g, int state, int x, int y, int w, int h) {
//        GTKStyle style = (GTKStyle)context.getStyle();
//        int size = style.getClassSpecificIntValue(context,
//                        "indicator-size", GTKIconFactory.DEFAULT_ICON_SIZE);
//        int offset = style.getClassSpecificIntValue(context,
//                        "indicator-spacing", GTKIconFactory.DEFAULT_ICON_SPACING);
//
//        ENGINE.paintCheck(g, context, Region.CHECK_BOX, "checkbutton",
//                x+offset, y+offset, size, size);
//    }
//
//    public void paintRadioButtonIcon(SynthContext context,
//            Graphics g, int state, int x, int y, int w, int h) {
//        GTKStyle style = (GTKStyle)context.getStyle();
//        int size = style.getClassSpecificIntValue(context,
//                        "indicator-size", GTKIconFactory.DEFAULT_ICON_SIZE);
//        int offset = style.getClassSpecificIntValue(context,
//                        "indicator-spacing", GTKIconFactory.DEFAULT_ICON_SPACING);
//
//        ENGINE.paintOption(g, context, Region.RADIO_BUTTON, "radiobutton",
//                x+offset, y+offset, size, size);
//    }
//
//    public void paintMenuArrowIcon(SynthContext context, Graphics g,
//            int state, int x, int y, int w, int h, ArrowType dir) {
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(
//                context.getRegion(), state);
//        ShadowType shadow = ShadowType.OUT;
//        if (gtkState == SynthConstants.MOUSE_OVER) {
//            shadow = ShadowType.IN;
//        }
//        ENGINE.paintArrow(g, context, Region.MENU_ITEM, gtkState, shadow,
//                dir, "menuitem", x + 3, y + 3, 7, 7);
//    }
//
//    public void paintCheckBoxMenuItemCheckIcon(SynthContext context,
//            Graphics g, int state, int x, int y, int w, int h) {
//
//        GTKStyle style = (GTKStyle)context.getStyle();
//        int size = style.getClassSpecificIntValue(context,"indicator-size",
//                GTKIconFactory.DEFAULT_TOGGLE_MENU_ITEM_SIZE);
//
//        ENGINE.paintCheck(g, context, Region.CHECK_BOX_MENU_ITEM, "check",
//                x + GTKIconFactory.CHECK_ICON_EXTRA_INSET,
//                y + GTKIconFactory.CHECK_ICON_EXTRA_INSET,
//                size, size);
//    }
//
//    public void paintRadioButtonMenuItemCheckIcon(SynthContext context,
//            Graphics g, int state, int x, int y, int w, int h) {
//
//        GTKStyle style = (GTKStyle)context.getStyle();
//        int size = style.getClassSpecificIntValue(context,"indicator-size",
//                GTKIconFactory.DEFAULT_TOGGLE_MENU_ITEM_SIZE);
//
//        ENGINE.paintOption(g, context, Region.RADIO_BUTTON_MENU_ITEM, "option",
//                x + GTKIconFactory.CHECK_ICON_EXTRA_INSET,
//                y + GTKIconFactory.CHECK_ICON_EXTRA_INSET,
//                size, size);
//    }
//
//    public void paintToolBarHandleIcon(SynthContext context, Graphics g,
//            int state, int x, int y, int w, int h, Orientation orientation) {
//        int gtkState = GTKLookAndFeel.synthStateToGTKState(
//                context.getRegion(), state);
//
//        // The orientation parameter passed down by Synth refers to the
//        // orientation of the toolbar, but the one we pass to GTK refers
//        // to the orientation of the handle.  Therefore, we need to swap
//        // the value here: horizontal toolbars have vertical handles, and
//        // vice versa.
//        orientation = (orientation == Orientation.HORIZONTAL) ?
//            Orientation.VERTICAL : Orientation.HORIZONTAL;
//
//        ENGINE.paintHandle(g, context, Region.TOOL_BAR, gtkState,
//                ShadowType.OUT, "handlebox", x, y, w, h, orientation);
//    }
//
//    public void paintAscendingSortIcon(SynthContext context,
//            Graphics g, int state, int x, int y, int w, int h) {
//        ENGINE.paintArrow(g, context, Region.TABLE, SynthConstants.ENABLED,
//                ShadowType.IN, ArrowType.UP, "arrow", x, y, w, h);
//    }
//
//    public void paintDescendingSortIcon(SynthContext context,
//            Graphics g, int state, int x, int y, int w, int h) {
//        ENGINE.paintArrow(g, context, Region.TABLE, SynthConstants.ENABLED,
//                ShadowType.IN, ArrowType.DOWN, "arrow", x, y, w, h);
//    }
//
//    /*
//     * Fill an area with color determined from this context's Style using the
//     * specified GTKColorType
//     */
//    private void fillArea(SynthContext context, Graphics g,
//                          int x, int y, int w, int h, ColorType colorType) {
//        if (context.getComponent().isOpaque()) {
//            Region id = context.getRegion();
//            int gtkState = GTKLookAndFeel.synthStateToGTKState(id,
//                    context.getComponentState());
//            GTKStyle style = (GTKStyle)context.getStyle();
//
//            g.setColor(style.getGTKColor(context, gtkState, colorType));
//            g.fillRect(x, y, w, h);
//        }
//    }
//
//    // Refer to GTKLookAndFeel for details on this.
//    static class ListTableFocusBorder extends AbstractBorder implements
//                          UIResource {
//
//        private boolean selectedCell;
//        private boolean focusedCell;
//
//        public static ListTableFocusBorder getSelectedCellBorder() {
//            return new ListTableFocusBorder(true, true);
//        }
//
//        public static ListTableFocusBorder getUnselectedCellBorder() {
//            return new ListTableFocusBorder(false, true);
//        }
//
//        public static ListTableFocusBorder getNoFocusCellBorder() {
//            return new ListTableFocusBorder(false, false);
//        }
//
//        public ListTableFocusBorder(boolean selectedCell, boolean focusedCell) {
//            this.selectedCell = selectedCell;
//            this.focusedCell = focusedCell;
//        }
//
//        private SynthContext getContext(Component c) {
//            SynthContext context = null;
//
//            ComponentUI ui = null;
//            if (c instanceof JLabel) {
//                ui = ((JLabel)c).getUI();
//            }
//
//            if (ui instanceof SynthUI) {
//                context = ((SynthUI)ui).getContext((JComponent)c);
//            }
//
//            return context;
//        }
//
//        public void paintBorder(Component c, Graphics g, int x, int y,
//                                int w, int h) {
//            if (focusedCell) {
//                SynthContext context = getContext(c);
//                int state = (selectedCell? SynthConstants.SELECTED:
//                             SynthConstants.FOCUSED | SynthConstants.ENABLED);
//
//                if (context != null) {
//                    GTKPainter.INSTANCE.paintFocus(context, g,
//                            Region.TABLE, state, "", x, y, w, h);
//                }
//            }
//        }
//
//        public Insets getBorderInsets(Component c, Insets i) {
//            SynthContext context = getContext(c);
//
//            if (context != null) {
//                i = context.getStyle().getInsets(context, i);
//            }
//
//            return i;
//        }
//
//        public boolean isBorderOpaque() {
//            return true;
//        }
//    }
//
//    // TitledBorder implementation for GTK L&F
//    static class TitledBorder extends AbstractBorder implements UIResource {
//
//        public void paintBorder(Component c, Graphics g, int x, int y,
//                                int w, int h) {
//            SynthContext context = getContext((JComponent)c);
//            Region id = context.getRegion();
//            int state = context.getComponentState();
//            int gtkState = GTKLookAndFeel.synthStateToGTKState(id, state);
//
//            synchronized (UNIXToolkit.GTK_LOCK) {
//                if (! ENGINE.paintCachedImage(g, x, y, w, h, id)) {
//                    ENGINE.startPainting(g, x, y, w, h, id);
//                    ENGINE.paintShadow(g, context, id, gtkState, ShadowType.ETCHED_IN,
//                                      "frame", x, y, w, h);
//                    ENGINE.finishPainting();
//                }
//            }
//        }
//
//        public Insets getBorderInsets(Component c, Insets i) {
//            SynthContext context = getContext((JComponent)c);
//            return context.getStyle().getInsets(context, i);
//        }
//
//        public boolean isBorderOpaque() {
//            return true;
//        }
//
//        private SynthStyle getStyle(JComponent c) {
//            return SynthLookAndFeel.getStyle(c, GTKEngine.CustomRegion.TITLED_BORDER);
//        }
//
//        private SynthContext getContext(JComponent c) {
//            int state = SynthConstants.DEFAULT;
//            return new SynthContext(c, GTKEngine.CustomRegion.TITLED_BORDER,
//                                    getStyle(c), state);
//        }
//    }
//}
